package com.dkd.flow.utils;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dkd.flow.domain.EProcessInstances;
import com.dkd.flow.domain.EProcessTask;
import com.dkd.flow.emums.FlowStatus;
import com.dkd.flow.emums.TaskActionType;
import com.dkd.flow.emums.TaskStatus;
import com.dkd.flow.emums.TaskType;
import com.dkd.flow.mapper.EProcessInstancesMapper;
import com.dkd.flow.mapper.EProcessTaskMapper;
import com.dkd.system.service.impl.SysUserServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Component
public class RevokeUtils {
    private static final Logger log = LoggerFactory.getLogger(RevokeUtils.class);
    @Autowired
    private EProcessTaskMapper eProcessTaskMapper;
    @Autowired
    private TaskCreate taskCreate;
    @Autowired
    EProcessInstancesMapper eProcessInstancesMapper;
    @Autowired
    SysUserServiceImpl sysUserService;
    @Autowired
    private NodeUtils nodeUtils;

    // 回退实例状态的映射
    public FlowStatus inferFlowStatusFromPreviousTask(TaskStatus previousStatus) {
        if (previousStatus == TaskStatus.RETURNED) {
            return FlowStatus.RETURNED;
        } else if (previousStatus == TaskStatus.RETURNED_ALL) {
            return FlowStatus.RETURNED_ALL;
        } else if (previousStatus == TaskStatus.REJECT_AND_END) {
            return FlowStatus.REJECT_AND_END;
        } else if (previousStatus == TaskStatus.INITIATE_APPLICATION || previousStatus == TaskStatus.DRAFT) {
            return FlowStatus.DRAFT;
        } else {
            return FlowStatus.PROCESSING;
        }
    }

    // 检查后续任务是否已处理
    public Boolean checkFollowingTasksNotProcessed(Long taskId) {
        Boolean flag = true;
        List<EProcessTask> taskList = eProcessTaskMapper.selectList(new QueryWrapper<EProcessTask>().eq("PRE_TASK_ID",
                taskId));
        for (EProcessTask task : taskList) {
            TaskStatus status = TaskStatus.getTaskStatusByValue(task.getTaskStatus()
                    .intValue());
            if (status == TaskStatus.APPROVAL || status == TaskStatus.RE_SUBMIT || status == TaskStatus.RE_SUBMIT_ALL) {
                flag = false;
                break;
            }
        }
        return flag;
    }

    // 创建后续任务
    public void createFollowingTasksWithStatus(EProcessInstances eProcessInstances,
            Long taskGroupId,
            TaskStatus taskStatus,
            Long actionTaskId,
            JSONObject formValue,
            TaskActionType taskActionType) {
        QueryWrapper<EProcessTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("TASK_GROUP_ID",
                taskGroupId);
        queryWrapper.eq("TASK_STATUS",
                TaskStatus.UNDER_APPROVAL.getValue().intValue());
        List<EProcessTask> taskList = eProcessTaskMapper.selectList(queryWrapper);
        if (taskList.size() > 0) {
            taskList.stream()
                    .forEach(task -> {
                        Long approveTaskId = IdUtil.getSnowflakeNextId();
                        taskCreate.approverTask(eProcessInstances,
                                nodeUtils.getApproverByTask(task),
                                task.getProcessDesignId(),
                                taskStatus,
                                approveTaskId,
                                actionTaskId,
                                null,
                                taskGroupId,
                                JSONObject.toJSONString(formValue),
                                taskActionType);
                    });
        }
    }

    // 创建并行任务
    public void createSynTasksWithStatus(
            EProcessTask approverCurTask, // 只能是审批人任务，不要传发起人任务，因为下面回取节点设计id
            EProcessInstances eProcessInstances,
            TaskStatus taskStatus,
            Long actionTaskId,
            Long newTaskGroupId,
            JSONObject formValue,
            TaskActionType taskActionType) {
        Long taskGroupId = approverCurTask.getTaskGroupId();
        if (taskGroupId != null) {
            // 只查询当前节点的并行任务
            QueryWrapper<EProcessTask> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("TASK_GROUP_ID", approverCurTask.getTaskGroupId());
            queryWrapper.eq("PROCESS_DESIGN_ID", approverCurTask.getProcessDesignId());
            queryWrapper.eq("TASK_TYPE", TaskType.APPROVER_TASK.getValue().intValue());
            queryWrapper.ne("ID", approverCurTask.getID()); // 排除当前任务
            List<EProcessTask> taskList = eProcessTaskMapper.selectList(queryWrapper);

            if (!taskList.isEmpty()) {
                taskList.stream()
                        .forEach(eProcessTask -> {
                            Long approverTaskId = IdUtil.getSnowflakeNextId();
                            taskCreate.approverTask(eProcessInstances,
                                    sysUserService.selectUserById(eProcessTask.getApprover()),
                                    approverCurTask.getProcessDesignId(),
                                    taskStatus,
                                    approverTaskId,
                                    actionTaskId,
                                    null,
                                    newTaskGroupId,
                                    JSONObject.toJSONString(formValue),
                                    taskActionType);
                        });
            }
        }
    }

    // 撤回的时候，检查是否已经生成下一个节点任务
    public Boolean checkNextTaskGenerated(Long curTaskGroupId,
            Long curTaskId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("task_group_id",
                curTaskGroupId);
        queryWrapper.eq("TASK_ACTION_TYPE",
                TaskActionType.LOG_TASK.getValue().intValue());
        List<EProcessTask> eProcessTaskList = eProcessTaskMapper.selectList(queryWrapper);
        EProcessTask curTask = eProcessTaskMapper.selectById(curTaskId);
        String processDesignId = curTask.getProcessDesignId();
        Boolean bool = eProcessTaskList.stream()
                .noneMatch(eProcessTask -> eProcessTask.getProcessDesignId().equals(processDesignId));
        return bool;
    }
}
